<!DOCTYPE html>
<html>
<head>
  <!-- Standard Meta -->
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

  <!-- Site Properities -->
  <title>Abyss</title>

  <link rel="stylesheet" type="text/css" href="<?php echo SCS::url()->base ?>/asset/semantic/semantic.min.css" />
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/googlecode.min.css">
  
  <script type="text/javascript" src="<?php echo SCS::url()->base ?>/asset/js/jquery-2.1.4.min.js"></script>
  <script type="text/javascript" src="<?php echo SCS::url()->base ?>/asset/semantic/semantic.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
  
  <style type="text/css">
  .ui.inverted.menu{background:#2185d0;}
  pre code {
      font: normal 12pt Menlo;
  	  font-family: "Menlo","Liberation Mono","Consolas","DejaVu Sans Mono","Ubuntu Mono","Courier New","andale mono","lucida console",monospace;
  }
  .ui.menu .item img.logo {
    margin-right: 1.5em;
  }
  .main.container {
    margin-top: 7em;
  }
  .wireframe {
    margin-top: 2em;
  }
  .ui.footer.segment {
    margin: 5em 0em 0em;
    padding: 5em 0em;
  }
  .slide-right{background:url(<?php echo SCS::url()->base?>/asset/image/slide_right.png) no-repeat;width:48px;display:inline-block;height:21px;vertical-align:top;}
 .section-block .section{display:none;}
pre code{font-size:14px;}
</style>

</head>
<body>

  <div class="ui fixed inverted menu">
    <div class="ui container">
      <div class="ui simple dropdown item">
        <img class="logo" src="<?php echo SCS::url()->base?>/asset/image/logo.png" onclick="window.location.href='<?php echo SCS::url()->create('doc')?>';">
        API <i class="dropdown icon"></i><?php echo str_repeat('&nbsp;', 10)?>
        <div class="menu">
          <?php foreach($this->docs as $desc=>$doc) {?>
          <div class="item">
            <i class="dropdown icon"></i>
            <span><?php echo $desc ?></span>
            <div class="menu">
                <?php foreach($doc as $d) {?>
                <a class="item" href="<?php echo SCS::url()->create('doc/'.str_replace('/', '::', $d['api']))?>"><?php echo $d['desc']?></a>
                <?php }?>
            </div>
          </div>
          <?php }?>
        </div>
      </div>
    </div>
  </div>

  <div class="ui main text container">
    <h1 class="ui header">Get Started</h1>
    项目地址：<a href="http://git.oschina.net/pycorvn/Abyss">http://git.oschina.net/pycorvn/Abyss</a>
    <h2>API调用</h2>
    <h3>认证授权</h3>
    
    <p>首先确保已申请到id号和私钥key。申请的id号和key如下：
<pre><code class="php hljs">&lt;?php
$id = 'test'; // 申请的id
$key = '29d03b2cd1df163770ffd73c6e541311'; // 分配的32位key
</code></pre>
    <p>向Abyss发起请求时，需在头部信息中附加两项meta元素：X-ABYSS-ID和X-ABYSS-KEY。X-ABYSS-ID即为申请的id号，X-ABYSS-KEY生成规则如下：
<pre><code class="php hljs">&lt;?php
$time = time();
$signKey = sha1($id.'ABYSS'.$key.'ABYSS'.$time).'.'.$time;
</code></pre>
    <p>附加到请求头信息中：
<pre><code class="php hljs">&lt;?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '<?php echo SCS::url()->create('', '', true)?>');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-ABYSS-ID: '.$id, 'X-ABYSS-KEY: '.$signKey]);
</code></pre>
    <p>完成上述配置后，接下来我们需要构造api查询语句发送到Abyss。
    <h3>构造查询语句</h3>
    <p>Abyss支持单个和一次性多个Api查询。所有的数据查询发送方式都使用POST方式传递：
<pre><code class="php hljs">&lt;?php
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
</code></pre>
    <h4>单API查询</h4>
<pre><code class="php hljs">&lt;?php
$query = [
    'api' => 'User/Create',
    'param' => ['username' => 'focrs', 'password' => '***'],
    'return' => '.'
]
</code></pre>
    <p>其中api为需要查询的API接口；param为提供给api接口的数据；return项可选，如果没有此配置或配置值为'.'，则返回接口默认的数据集。当接口默认返回的数据格式为对象或关联数组时，如果只想返回其中某一个属性如：id，return可设置为：
<pre><code class="php hljs">&lt;?php
$query = [
    'api' => 'User/Create',
    'param' => ['username' => 'focrs', 'password' => '***'],
    'return' => '.id'
]
</code></pre>
    <p>发送和接收数据：
<pre><code class="php hljs">&lt;?php
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(compact('query')));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response);
if($result && $result->status == 1) {
    var_dump($result->data); // 处理返回的数据
} else {
    throw new Exception($response);
}
</code></pre>
    
    <h4>多API查询</h4>
    <p>多API查询的应用场景为多任务处理或事务处理，调用后每个api均会按调用顺序返回数据(没有则返回null)，查询语句构造方式如下：
<pre><code class="php hljs">&lt;?php
$query = [[
    'api' => 'User/Create',
    'param' => ['username' => 'focrs', 'password' => '***'],
    'bind' => ['::userId' => '.id'], // 调用下一个api需要用到的参数：userId
    'return' => '.id'
], [
    'api' => 'User/Status',
    'param' => ['userId' => '::userId']
], [
    'api' => 'Product/Candy'
]];
</code></pre>
    <p>将每个API请求构造方式放到一个数组中，就变成了多API请求。多API之前可传递共享数据，上例中预绑定了一个::userId，值为第一个API返回的id属性，将其作为userId参数传递给第二个API。

<h2>API开发</h2>
<p>在<?php echo SC_APP_PATH?>/controller目录下创建一个类文件：UserController.class.php，基本代码如下：
<pre><code class="php hljs">&lt;?php
class UserController extends SCController {
        
    public function __construct() {
        parent::__construct();
    }
}     
</code></pre>
<p>如果需要开发一个创建用户的API：User/Create，则需在UserController中创建一个新方法Create:
<pre><code class="php hljs">&lt;?php
public function Create($token) {
    Abyss::Instance()->Announce($token, [
        'api' => __METHOD__,
        'desc' => '创建用户',
        'param' => [
            [Abyss::TYPE_STRING, 'username', '用户名', 'focrs', true],
            [Abyss::TYPE_STRING, 'password', '密码', '******', true],
        ],
        'return' => [Abyss::TYPE_OBJECT, null, '用户信息', [
            [Abyss::TYPE_INTEGER, 'userId', '用户Id', 11]
        ]]
    ]);
    
    $user = SCS::curd('User')->create([
       'username' => Abyss::Instance()->GetParam('username'),
       'password' => md5(Abyss::Instance()->GetParam('password')),
    ]);
    
    return ['userId' => $user->id];
}
</code></pre>
</div>


  
<script type="text/javascript">
$(function() {
	hljs.configure({useBR: false});
	
      $('pre code').each(function(i, block) {
        hljs.highlightBlock(block);
      });

    $('.section-block .menu .item').bind('click', function() {
        var section = $(this).data('section'), $this = $(this);
        $(this).closest('.section-block').find('.section').each(function() {
            $this.addClass('active').siblings('.item').removeClass('active');
        	if($(this).hasClass(section)) {
            	$(this).show();
        	} else {
     		    $(this).hide();
        	}  
        });
    });
});
</script>
</body>

</html>